package com.zlz.news.exception;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * @author 钟良
 * @desc
 * @date:2017/7/6 10:36 Copyright (c) 2017, DaChen All Rights Reserved.
 */
@ControllerAdvice
public class ExceptionHandlerAdvice {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionHandlerAdvice.class);

    @ExceptionHandler(value = {Exception.class, RuntimeException.class})
    public void handleErrors(HttpServletRequest request, HttpServletResponse response, Exception e)
        throws Exception {
        logger.error("接口请求错误：{}", request.getRequestURI());
        logger.error("错误内容：{}", e);
        e.printStackTrace();

        int errorCode = 100100;
        String error = "服务器繁忙，请稍后再试！";

        if (e instanceof MissingServletRequestParameterException) {
            errorCode = 100101;
            error = "请求参数验证失败，缺少必填参数或参数错误";
        } else if (e instanceof BindException) {
            errorCode = 1010101;
            error = "请求参数验证失败，缺少必填参数或参数错误";

            BindException ex = (BindException) e;
            BindingResult bindingResult = ex.getBindingResult();
            List<ObjectError> errorList = bindingResult.getAllErrors();
            StringBuilder sb = new StringBuilder();
            for (ObjectError objectError:errorList) {
                if (StringUtils.isNotBlank(objectError.getDefaultMessage())) {
                    sb.append(objectError.getDefaultMessage());
                    sb.append("；");
                }
            }
            if (sb.length()>0) {
                sb.setLength(sb.length()-1);
                error = sb.toString();
            }
        } else if (e instanceof MethodArgumentNotValidException) {
            errorCode = 1010101;
            error = "请求参数验证失败，缺少必填参数或参数错误";

            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
            BindingResult bindingResult = ex.getBindingResult();
            List<ObjectError> errorList = bindingResult.getAllErrors();
            StringBuilder sb = new StringBuilder();
            for (ObjectError objectError:errorList) {
                if (StringUtils.isNotBlank(objectError.getDefaultMessage())) {
                    sb.append(objectError.getDefaultMessage());
                    sb.append("；");
                }
            }
            if (sb.length()>0) {
                sb.setLength(sb.length()-1);
                error = sb.toString();
            }
        }else if (e instanceof ServiceException) {
            ServiceException ex = ((ServiceException) e);
            errorCode = Objects.isNull(ex.getResultCode()) ? 0 : ex.getResultCode();
            error = ex.getMessage();
        }

        Map<String, Object> map = Maps.newHashMap();
        map.put("errorCode", errorCode);
        map.put("error", error);
        map.put("success", false);
        map.put("data", new Object());

        String text = JSON.toJSONString(map);

        response.setContentType("application/json; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(text);
        response.getWriter().flush();
    }


}
